/**
 * 
 */
package de.global42.clubapp.interceptors;

import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.UriInfo;

import de.global42.clubapp.util.QueryParamMap;
import de.global42.clubapp.util.RequestParam;

/**
 * @author lutz
 *
 */
public class RESTfulInterceptor {



	private static final String QUALIFIED_CLASS_NAME = "de.global42.clubapp.interceptors.RESTfulInterceptor";
	private static final String EXPECTED_PARAMS = "EXPECTED_PARAMS_";
	
	public static final RequestParam[] EXPECTED_PARAMS_TEST = new RequestParam[]{new RequestParam("id", false)};
	public static final RequestParam[] EXPECTED_PARAMS_REGISTER = new RequestParam[]{};
	public static final RequestParam[] EXPECTED_PARAMS_GETMISSIONS = new RequestParam[]{new RequestParam("client", false), new RequestParam("lastupdated", true)};
	public static final RequestParam[] EXPECTED_PARAMS_GETCLIENTMISSIONS = new RequestParam[]{new RequestParam("client", false)};
	public static final RequestParam[] EXPECTED_PARAMS_ENTERVALIDATIONCODE = new RequestParam[]{new RequestParam("client", false), new RequestParam("validationcode", false), new RequestParam("venue", false)};
	
	/**
	 * 
	 */
	public RESTfulInterceptor() {}

	/**
	 * @param ic
	 * @return
	 * @throws Exception
	 */
	@AroundInvoke
	public Object manageRequest(InvocationContext ic) throws Exception {
		UriInfo uriInfo = (UriInfo) ic.getParameters()[0];
		QueryParamMap parameters = extractNeededQueryParams(uriInfo.getQueryParameters(), ic.getMethod().getName());
		ic.setParameters(new Object[]{uriInfo,parameters});
		return ic.proceed();
	}

	private QueryParamMap extractNeededQueryParams(MultivaluedMap<String, String> queryParameters, String methodName) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException, ClassNotFoundException {
		QueryParamMap queryParams = new QueryParamMap();
		String fieldName = EXPECTED_PARAMS + methodName.toUpperCase();
		RequestParam[] expectedParams = (RequestParam[]) Class.forName(QUALIFIED_CLASS_NAME).getField(fieldName).get(this);
		
		for (RequestParam expectedParam : expectedParams) {
			String paramValue  = null;
			if (queryParameters.containsKey(expectedParam.getName())) {
				paramValue = queryParameters.getFirst(expectedParam.getName());
			}
			else if (!expectedParam.isOptional()) {
				throw new IllegalArgumentException();//TODO: write exceptionmessage
			}
			queryParams.put(expectedParam.getName(), paramValue);
		}
		
		return queryParams;
	}

}
